﻿using Microsoft.CSharp;
using RemoteAccess;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Reflection;

namespace AvalonEdit
{

    [Serializable]
  public  class DyCompile
    {
        public event Action<double[]> m;
        public DyCompile()
        {
           
        }

        AppDomainSetup objSetup ;
        AppDomain objAppDomain;
        RemoteLoaderFactory factory;
        public IRemoteInterface objRemote;
        public object objObject;
        public bool InitializeDynamic()
        {
            //初始化
            // 0. Create an addtional AppDomain
            objSetup = new AppDomainSetup();
            objSetup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
            objAppDomain = AppDomain.CreateDomain("MyAppDomain", null, objSetup);

            //引用
            // 4. Invoke the method by using Reflection
            factory = (RemoteLoaderFactory)objAppDomain.CreateInstance("RemoteAccess", "RemoteAccess.RemoteLoaderFactory").Unwrap();

            // with help of factory, create a real 'LiveClass' instance
            objObject = factory.Create("DynamicalCode.dll","Dynamicly.DyCommun", null);

            if (objObject == null)
            {
               // this.txtResult.Text = "Error: " + "Couldn't load class.";   //程序集不存在
                return false;
            }
            objRemote = (IRemoteInterface)objObject;

            // t();
            return true;


            //函数参数
        }
        public void UnLoad()
        {
            try
            {

                //EventInfo evt = objObject.GetType().GetEvent(
                //    "OnChange",
                //    BindingFlags.NonPublic
                //    | BindingFlags.Instance
                //    | BindingFlags.Public);

                //evt.RemoveEventHandler(objObject, new EventHandler(InitializeDynamic));

                objRemote = null;
                objObject = null;
                AppDomain.Unload(objAppDomain);

            }
            catch
            {

            }
            //释放资源

        }

        public string DynamicLoad()
        {
            double[] d = new double[] { 1,2,3,4,5};
            List<double[]> g = new List<double[]>();
            g.Add(d);
            object[] objCodeParms = new object[1];
            objCodeParms[0] =g;
            //调用
            string strResult = (string)objRemote.Invoke("GetTime", objCodeParms);
            return strResult;
        }


        public string Compile(string strSourceCode)
        {
            // 1.Create a new CSharpCodePrivoder instance
            CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();
            // 2.Sets the runtime compiling parameters by crating a new CompilerParameters instance
            CompilerParameters objCompilerParameters = new CompilerParameters();
            objCompilerParameters.ReferencedAssemblies.Add("System.dll");
            objCompilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
            objCompilerParameters.ReferencedAssemblies.Add("RemoteAccess.dll");
            objCompilerParameters.ReferencedAssemblies.Add("halcondotnet.dll");
            // L设置程序集 halcondotnet.dll
            objCompilerParameters.GenerateInMemory = false;
            objCompilerParameters.OutputAssembly = "DynamicalCode.dll";



            // 编译
            CompilerResults cr = objCSharpCodePrivoder.CompileAssemblyFromSource(objCompilerParameters, strSourceCode);

            //编辑结果
            if (cr.Errors.HasErrors)
            {
                string strErrorMsg = cr.Errors.Count.ToString() + " Errors:";

                for (int x = 0; x < cr.Errors.Count; x++)
                {
                    strErrorMsg = strErrorMsg + "\r\nLine: " +
                                 cr.Errors[x].Line.ToString() + "\r\n " +
                                 cr.Errors[x].ErrorText;
                }

               // this.txtResult.Text = strErrorMsg;
              //  MessageBox.Show("There were build erros, please modify your code.", "Compiling Error");
                return strErrorMsg;
            }
            return ".....编译完成 ";

        }


       public void InitializeDynamic(object sender, EventArgs e)
        {
            MessageBox.Show("事件");
        }

    }

}
